package com.metadata_system.common.utils;

import io.jsonwebtoken.lang.Assert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component("redisUtils")
@Slf4j
public class RedisUtil {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 设置-值
     *
     * @param key
     * @param value
     */
    public void setValue(String key, Object value) {
        if (value == null) {
            Object currValue = this.getValue(key, Object.class);
            if (currValue == null) {
                return;
            }
            try {
                Set<String> keys = stringRedisTemplate.keys("*");
                ValueOperations<String, String> stringStringValueOperations = this.stringRedisTemplate.opsForValue();
                this.stringRedisTemplate.delete(keys);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            String valueStr = "";
            if (value instanceof String || value instanceof Integer || value instanceof Boolean) {
                valueStr = String.valueOf(value);
            } else {
                valueStr = JSON.toJSONString(value);
            }
            this.stringRedisTemplate.opsForValue().set(key, valueStr);
        }
    }

    /**
     * 设置-值(带有效期)
     *
     * @param key
     * @param value
     * @param expireSeconds
     */
    public void setValue(String key, Object value, int expireSeconds) {
        String valueStr = "";
        if (value instanceof String || value instanceof Integer || value instanceof Boolean) {
            valueStr = String.valueOf(value);
        } else {
            valueStr = JSON.toJSONString(value);
        }
        this.stringRedisTemplate.opsForValue().set(key, valueStr, expireSeconds, TimeUnit.SECONDS);
    }

    /**
     * 获取-值
     *
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getValue(String key, Class<T> clazz) {
        String valueStr = null;
        valueStr = stringRedisTemplate.opsForValue().get(key);
        if (valueStr == null || valueStr.equals("null")) {
            return null;
        }
        T t = null;
        // 如果不是对象/数组的话直接返回
        if (!(StringUtils.startsWith(valueStr, "{"))) {
            return (T) valueStr;
        }
        try {
            t = JSON.parseObject(valueStr).toJavaObject(clazz);
        } catch (Exception e) {
            log.info("获取缓存出错", e);
        }
        return t;
    }

    public void del(final String key) {
        Assert.hasText(key,"Key is not empty.");
        this.stringRedisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection conn) throws DataAccessException {
                RedisSerializer<String> serializer = stringRedisTemplate.getStringSerializer();
                return conn.del(serializer.serialize(key));
            }
        });
    }

}
